/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: I/O memory remap for kernel space
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-08-14     JasonHu           Init
 */

#include <base/ioremap.h>
#include <base/vmspace.h>
#include <arch/process.h>
#include <base/debug.h>
#include <base/page.h>
#include <base/log.h>

NX_Vmspace gKernelVmspace;

void * NX_IoRemap(void * paddr, NX_Size size)
{
    void * mapAddr = NX_NULL;

    if (!paddr || !size)
    {
        return NX_NULL;
    }

    /* map in kernel vmspace */
    if (NX_VmspaceMapWithPhy(&gKernelVmspace, 0, (NX_Addr)paddr, size, NX_PAGE_ATTR_KERNEL, NX_VMSPACE_NOMERGE | NX_VMSPACE_SHAREMEM, &mapAddr) != NX_EOK)
    {
        return NX_NULL;
    }

    return mapAddr;
}

NX_Error NX_IoUnmap(void * vaddr)
{
    NX_Vmnode * vmnode;

    if (!vaddr)
    {
        return NX_EINVAL;
    }

    vmnode = NX_VmspaceFindNodeUnder(&gKernelVmspace, (NX_Addr)vaddr);

    if (vmnode == NX_NULL)
    {
        return NX_ENOSRCH;
    }

    return NX_VmspaceUnmap(&gKernelVmspace, vmnode->start, vmnode->end - vmnode->start, vmnode->flags);
}

void NX_IoRemapInit(void)
{
    /* get kernel mmu info */
    NX_ASSERT(NX_MmuGetKernelTable());

    NX_VmspaceInit(&gKernelVmspace, gKernelMmu.virStart, gKernelMmu.virEnd, 
                    NX_KernelGetSegmentStart("text"), NX_KernelGetSegmentEnd("bss"), /* kernel text, data, bss */
                    NX_PAGE_ALIGNUP(NX_KernelGetSegmentEnd("bss")), gKernelMmu.earlyEnd, /* heap in [bss - map] */
                    gKernelMmu.earlyEnd, gKernelMmu.virEnd, /* map area in [early end - kernel virtual end] */
                    0, 0);  /* no statck area */

    /* copy mmu info from kernel mmu */
    gKernelVmspace.mmu = gKernelMmu;
}
